package com.leyou.item.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.dto.PageDTO;
import com.leyou.common.exception.LyException;
import com.leyou.item.entity.*;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.*;
import com.leyou.user.dto.SkuDTO;
import com.leyou.user.dto.SpuDTO;
import com.leyou.user.dto.SpuDetailDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 虎哥
 */
@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {

    @Autowired
    CategoryService categoryService;

    @Autowired
    BrandService brandService;

    @Autowired
    SpuDetailService detailService;

    @Autowired
    SkuService skuService;

    @Override
    public PageDTO<SpuDTO> querySpuByPage(Integer page, Integer rows, Boolean saleable, Long categoryId, Long brandId, Long id) {
        // 1.分页信息
        page = Math.max(Math.min(page, 100), 1);
        rows = Math.max(rows, 5);

        // 2.查询条件
        Spu spu = new Spu();
        spu.setId(id);
        spu.setCid3(categoryId);
        spu.setBrandId(brandId);
        spu.setSaleable(saleable);
        QueryWrapper<Spu> queryWrapper = new QueryWrapper<>(spu);
        // 3.查询数据
        IPage<Spu> result = page(new Page<>(page, rows), queryWrapper);

        // 4.处理结果
        List<Spu> records = result.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            throw new LyException(400, "商品id不存在");
        }
        // 4.1.DTO转换
        List<SpuDTO> list = SpuDTO.convertEntityList(records);
        // 4.2.处理分类和品牌名称
        for (SpuDTO spuDTO : list) {
            handleCategoryAndBrandName(spuDTO);
        }

        return new PageDTO<>(result.getTotal(), result.getPages(), list);
    }

    @Transactional
    @Override
    public void saveGoods(SpuDTO spuDTO) {
        // 1.新增Spu
        Spu spu = spuDTO.toEntity(Spu.class);
        spu.setSaleable(false);
        boolean success = save(spu);
        if (!success) {
            throw new LyException(500, "新增商品失败");
        }
        // 2.新增SpuDetail
        SpuDetail spuDetail = spuDTO.getSpuDetail().toEntity(SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        success = detailService.save(spuDetail);
        if (!success) {
            throw new LyException(500, "新增商品详情失败");
        }
        // 3.新增Sku
        List<Sku> list = spuDTO.getSkus().stream().map(skuDTO -> {
            Sku sku = skuDTO.toEntity(Sku.class);
            sku.setSaleable(false);
            sku.setSpuId(spu.getId());
            return sku;
        }).collect(Collectors.toList());
        // 批量新增
        skuService.saveBatch(list);
    }

    @Transactional
    @Override
    public void updateSaleable(Long id, Boolean saleable) {
        // 1.更新SPU
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
        boolean success = updateById(spu);
        if (!success) {
            throw new LyException(500, "更新失败");
        }
        // 2.更新sku
        success =skuService.update().eq("spu_id", id).set("saleable", saleable).update();
        if (!success) {
            throw new LyException(500, "更新失败");
        }
    }

    @Override
    public SpuDTO queryGoodsById(Long id) {
        // 1.查询spu
        // 1.1.查询
        Spu spu = getById(id);
        if (spu == null) {
            throw new LyException(400, "商品id不存在！");
        }
        // 1.2.转换DTO
        SpuDTO spuDTO = new SpuDTO(spu);

        // 2.查询spuDetail
        SpuDetail detail = detailService.getById(id);
        if (detail == null) {
            throw new LyException(400, "商品id不存在！");
        }
        spuDTO.setSpuDetail(new SpuDetailDTO(detail));

        // 3.查询sku
        List<Sku> list = skuService.query().eq("spu_id", id).list();
        if(CollectionUtils.isEmpty(list)){
            throw new LyException(400, "商品id不存在！");
        }
        spuDTO.setSkus(SkuDTO.convertEntityList(list));

        // 4.准备商品分类和品牌名称
        handleCategoryAndBrandName(spuDTO);

        return spuDTO;
    }


    @Transactional
    @Override
    public void updateGoods(SpuDTO spuDTO) {
        // 1.修改spu
        // 1.1.判断是否存在spu的id，有说明需要修改，没有说明不需要
        Long spuId = spuDTO.getId();
        if(spuId != null){
            // 1.2.spu需要修改，更新spu, 转换dto
            Spu spu = spuDTO.toEntity(Spu.class);
            // 1.3.更新
            boolean success = updateById(spu);
            if(!success){
                // 更新失败，抛出异常
                throw new LyException(500, "更新商品失败！");
            }
        }
        // 2.修改spuDetail
        SpuDetailDTO detailDTO = spuDTO.getSpuDetail();
        // 2.1.判断是否为null
        if (detailDTO != null && detailDTO.getSpuId() != null) {
            // 2.2.spuDetail存在，需要修改，转换DTO
            SpuDetail detail = detailDTO.toEntity(SpuDetail.class);
            boolean success = detailService.updateById(detail);
            if(!success){
                // 更新失败，抛出异常
                throw new LyException(500, "更新商品失败！");
            }
        }
        // 3.修改sku
        List<SkuDTO> dtoList = spuDTO.getSkus();
        // 3.1.判断是否包含sku
        if(CollectionUtils.isEmpty(dtoList)){
            return;
        }
        // 3.2.转换DTO，并将sku根据saleable是否为null来分组。null，是新增或修改，不是null是删除
        Map<Boolean, List<Sku>> map = dtoList.stream()
                .map(skuDTO -> skuDTO.toEntity(Sku.class))
                .collect(Collectors.groupingBy(sku -> sku.getSaleable() == null));

        // 3.3.获取要新增或修改的sku
        List<Sku> insertOrUpdateList = map.get(true);
        // 如果不为空，则修改或新增
        if(!CollectionUtils.isEmpty(insertOrUpdateList)) {
            skuService.saveOrUpdateBatch(insertOrUpdateList);
        }

        // 3.4.获取要删除的sku
        List<Sku> deleteSkuList = map.get(false);
        if(!CollectionUtils.isEmpty(deleteSkuList)){
            // 存在要删除的sku
            List<Long> idList = deleteSkuList.stream().map(Sku::getId).collect(Collectors.toList());
            // 删除
            skuService.removeByIds(idList);
        }
    }

    private void handleCategoryAndBrandName(SpuDTO spuDTO) {
        // 处理品牌名称
        Brand brand = brandService.getById(spuDTO.getBrandId());
        if (brand != null) {
            spuDTO.setBrandName(brand.getName());
        }
        // 处理分类名称
        Collection<Category> categories = categoryService.listByIds(spuDTO.getCategoryIds());
        if (!CollectionUtils.isEmpty(categories)) {
            spuDTO.setCategoryName(
                    categories.stream().map(Category::getName).collect(Collectors.joining("/")));
        }
    }


}






















